Object.defineProperty(exports, "__esModule", {
    value: !0
});

var _createClass = function() {
    function i(t, s) {
        for (var e = 0; e < s.length; e++) {
            var i = s[e];
            i.enumerable = i.enumerable || !1, i.configurable = !0, "value" in i && (i.writable = !0), 
            Object.defineProperty(t, i.key, i);
        }
    }
    return function(t, s, e) {
        return s && i(t.prototype, s), e && i(t, e), t;
    };
}();

function _toConsumableArray(t) {
    if (Array.isArray(t)) {
        for (var s = 0, e = Array(t.length); s < t.length; s++) e[s] = t[s];
        return e;
    }
    return Array.from(t);
}

function _classCallCheck(t, s) {
    if (!(t instanceof s)) throw new TypeError("Cannot call a class as a function");
}

var QR = require("./qrcode.js"), GD = require("./gradient.js"), Painter = function() {
    function e(t, s) {
        _classCallCheck(this, e), this.ctx = t, this.data = s, this.globalWidth = {}, this.globalHeight = {};
    }
    return _createClass(e, [ {
        key: "paint",
        value: function(t) {
            this.style = {
                width: this.data.width.toPx(),
                height: this.data.height.toPx()
            }, this._background();
            var s = !0, e = !1, i = void 0;
            try {
                for (var h = this.data.views[Symbol.iterator](); !(s = (a = h.next()).done); s = !0) {
                    var a = a.value;
                    this._drawAbsolute(a);
                }
            } catch (t) {
                e = !0, i = t;
            } finally {
                try {
                    !s && h.return && h.return();
                } finally {
                    if (e) throw i;
                }
            }
            this.ctx.draw(!1, function() {
                t();
            });
        }
    }, {
        key: "_background",
        value: function() {
            this.ctx.save();
            var t = this.style, s = t.width, e = t.height, t = this.data.background;
            this.ctx.translate(s / 2, e / 2), this._doClip(this.data.borderRadius, s, e), t ? t.startsWith("#") || t.startsWith("rgba") || "transparent" === t.toLowerCase() ? (this.ctx.fillStyle = t, 
            this.ctx.fillRect(-s / 2, -e / 2, s, e)) : GD.api.isGradient(t) ? (GD.api.doGradient(t, s, e, this.ctx), 
            this.ctx.fillRect(-s / 2, -e / 2, s, e)) : this.ctx.drawImage(t, -s / 2, -e / 2, s, e) : (this.ctx.fillStyle = "#fff", 
            this.ctx.fillRect(-s / 2, -e / 2, s, e)), this.ctx.restore();
        }
    }, {
        key: "_drawAbsolute",
        value: function(t) {
            if (t) switch (t.css && t.css.length && (t.css = Object.assign.apply(Object, _toConsumableArray(t.css))), 
            t.type) {
              case "image":
                this._drawAbsImage(t);
                break;

              case "text":
                this._fillAbsText(t);
                break;

              case "rect":
                this._drawAbsRect(t);
                break;

              case "qrcode":
                this._drawQRCode(t);
            }
        }
    }, {
        key: "_doClip",
        value: function(t, s, e) {
            t && s && e && (t = Math.min(t.toPx(), s / 2, e / 2), this.ctx.globalAlpha = 0, 
            this.ctx.fillStyle = "white", this.ctx.beginPath(), this.ctx.arc(-s / 2 + t, -e / 2 + t, t, +Math.PI, 1.5 * Math.PI), 
            this.ctx.lineTo(s / 2 - t, -e / 2), this.ctx.arc(s / 2 - t, -e / 2 + t, t, 1.5 * Math.PI, 2 * Math.PI), 
            this.ctx.lineTo(s / 2, e / 2 - t), this.ctx.arc(s / 2 - t, e / 2 - t, t, 0, .5 * Math.PI), 
            this.ctx.lineTo(-s / 2 + t, e / 2), this.ctx.arc(-s / 2 + t, e / 2 - t, t, .5 * Math.PI, +Math.PI), 
            this.ctx.closePath(), this.ctx.fill(), getApp().systemInfo && getApp().systemInfo.version <= "6.6.6" && "ios" === getApp().systemInfo.platform || this.ctx.clip(), 
            this.ctx.globalAlpha = 1);
        }
    }, {
        key: "_doBorder",
        value: function(t, s, e) {
            var i, h, a;
            t.css && (i = (h = t.css).borderRadius, a = h.borderWidth, h = h.borderColor, a && (this.ctx.save(), 
            this._preProcess(t, !0), t = void 0, t = i ? Math.min(i.toPx(), s / 2, e / 2) : 0, 
            a = a.toPx(), this.ctx.lineWidth = a, this.ctx.strokeStyle = h || "black", this.ctx.beginPath(), 
            this.ctx.arc(-s / 2 + t, -e / 2 + t, t + a / 2, +Math.PI, 1.5 * Math.PI), this.ctx.lineTo(s / 2 - t, -e / 2 - a / 2), 
            this.ctx.arc(s / 2 - t, -e / 2 + t, t + a / 2, 1.5 * Math.PI, 2 * Math.PI), this.ctx.lineTo(s / 2 + a / 2, e / 2 - t), 
            this.ctx.arc(s / 2 - t, e / 2 - t, t + a / 2, 0, .5 * Math.PI), this.ctx.lineTo(-s / 2 + t, e / 2 + a / 2), 
            this.ctx.arc(-s / 2 + t, e / 2 - t, t + a / 2, .5 * Math.PI, +Math.PI), this.ctx.closePath(), 
            this.ctx.stroke(), this.ctx.restore()));
        }
    }, {
        key: "_preProcess",
        value: function(t, s) {
            var e = 0, i = void 0, h = void 0;
            switch (t.type) {
              case "text":
                for (var a = t.text.split("\n"), r = 0; r < a.length; ++r) "" === a[r] && (a[r] = " ");
                var c = "bold" === t.css.fontWeight ? "bold" : "normal";
                t.css.fontSize = t.css.fontSize || "20rpx", this.ctx.font = "normal " + c + " " + t.css.fontSize.toPx() + "px " + (t.css.fontFamily || "sans-serif");
                for (var o = 0, l = [], n = 0; n < a.length; ++n) {
                    var x = this.ctx.measureText(a[n]).width, d = t.css.width ? t.css.width.toPx() : x, x = Math.ceil(x / d), e = e < d ? d : e;
                    o += x, l[n] = x;
                }
                o = t.css.maxLines < o ? t.css.maxLines : o;
                c = (t.css.lineHeight || t.css.fontSize).toPx(), i = c * o, h = {
                    lines: o,
                    lineHeight: c,
                    textArray: a,
                    linesArray: l
                };
                break;

              case "image":
                c = getApp().systemInfo.pixelRatio ? getApp().systemInfo.pixelRatio : 2;
                t.css && (t.css.width || (t.css.width = "auto"), t.css.height || (t.css.height = "auto")), 
                !t.css || "auto" === t.css.width && "auto" === t.css.height ? (e = Math.round(t.sWidth / c), 
                i = Math.round(t.sHeight / c)) : "auto" === t.css.width ? (i = t.css.height.toPx(), 
                e = t.sWidth / t.sHeight * i) : i = "auto" === t.css.height ? (e = t.css.width.toPx(), 
                t.sHeight / t.sWidth * e) : (e = t.css.width.toPx(), t.css.height.toPx());
                break;

              default:
                if (!t.css.width || !t.css.height) return void console.error("You should set width and height");
                e = t.css.width.toPx(), i = t.css.height.toPx();
            }
            var g, u = void 0;
            u = t.css && t.css.right ? "string" == typeof t.css.right ? this.style.width - t.css.right.toPx(!0) : (g = t.css.right, 
            this.style.width - g[0].toPx(!0) - this.globalWidth[g[1]] * (g[2] || 1)) : t.css && t.css.left ? "string" == typeof t.css.left ? t.css.left.toPx(!0) : (g = t.css.left)[0].toPx(!0) + this.globalWidth[g[1]] * (g[2] || 1) : 0;
            var f = void 0;
            f = t.css && t.css.bottom ? this.style.height - i - t.css.bottom.toPx(!0) : t.css && t.css.top ? "string" == typeof t.css.top ? t.css.top.toPx(!0) : (b = t.css.top)[0].toPx(!0) + this.globalHeight[b[1]] * (b[2] || 1) : 0;
            var b = t.css && t.css.rotate ? this._getAngle(t.css.rotate) : 0;
            switch (t.css && t.css.align ? t.css.align : t.css && t.css.right ? "right" : "left") {
              case "center":
                this.ctx.translate(u, f + i / 2);
                break;

              case "right":
                this.ctx.translate(u - e / 2, f + i / 2);
                break;

              default:
                this.ctx.translate(u + e / 2, f + i / 2);
            }
            return this.ctx.rotate(b), !s && t.css && t.css.borderRadius && "rect" !== t.type && this._doClip(t.css.borderRadius, e, i), 
            this._doShadow(t), t.id && (this.globalWidth[t.id] = e, this.globalHeight[t.id] = i), 
            {
                width: e,
                height: i,
                x: u,
                y: f,
                extra: h
            };
        }
    }, {
        key: "_doBackground",
        value: function(t) {
            this.ctx.save();
            var s, e, i = this._preProcess(t, !0), h = i.width, a = i.height, r = t.css, c = r.background, i = r.padding, r = [ 0, 0, 0, 0 ];
            i && (1 === (i = i.split(/\s+/)).length && (r = [ s = i[0].toPx(), s, s, s ]), 2 === i.length && (r = [ s = i[0].toPx(), e = i[1].toPx(), s, e ]), 
            3 === i.length && (r = [ i[0].toPx(), e = i[1].toPx(), i[2].toPx(), e ]), 4 === i.length && (r = [ i[0].toPx(), i[1].toPx(), i[2].toPx(), i[3].toPx() ]));
            h = h + r[1] + r[3], r = a + r[0] + r[2];
            this._doClip(t.css.borderRadius, h, r), GD.api.isGradient(c) ? GD.api.doGradient(c, h, r, this.ctx) : this.ctx.fillStyle = c, 
            this.ctx.fillRect(-h / 2, -r / 2, h, r), this.ctx.restore();
        }
    }, {
        key: "_drawQRCode",
        value: function(t) {
            this.ctx.save();
            var s = this._preProcess(t), e = s.width, s = s.height;
            QR.api.draw(t.content, this.ctx, -e / 2, -s / 2, e, s, t.css.background, t.css.color), 
            this.ctx.restore(), this._doBorder(t, e, s);
        }
    }, {
        key: "_drawAbsImage",
        value: function(t) {
            var s, e, i, h, a, r, c;
            t.url && (this.ctx.save(), s = (c = this._preProcess(t)).width, e = c.height, i = t.sWidth, 
            h = t.sHeight, r = a = 0, c = s / e, t.sWidth / t.sHeight <= c ? (h = i / c, r = Math.round((t.sHeight - h) / 2)) : (i = h * c, 
            a = Math.round((t.sWidth - i) / 2)), t.css && "scaleToFill" === t.css.mode ? this.ctx.drawImage(t.url, -s / 2, -e / 2, s, e) : this.ctx.drawImage(t.url, a, r, i, h, -s / 2, -e / 2, s, e), 
            this.ctx.restore(), this._doBorder(t, s, e));
        }
    }, {
        key: "_fillAbsText",
        value: function(t) {
            if (t.text) {
                t.css.background && this._doBackground(t), this.ctx.save();
                var s = this._preProcess(t, t.css.background && t.css.borderRadius), e = s.width, i = s.height, s = s.extra;
                this.ctx.fillStyle = t.css.color || "black";
                var h = s.lines, a = s.lineHeight, r = s.textArray, c = s.linesArray;
                if (t.id) {
                    for (var o = 0, l = 0; l < r.length; ++l) o = this.ctx.measureText(r[l]).width > o ? this.ctx.measureText(r[l]).width : o;
                    this.globalWidth[t.id] = !e || o < e ? o : e;
                }
                for (var n = 0, x = 0; x < r.length; ++x) for (var d = Math.round(r[x].length / c[x]), g = 0, u = 0, f = 0; f < c[x] && !(h <= n); ++f) {
                    u = d;
                    for (var b = r[x].substr(g, u), P = this.ctx.measureText(b).width; g + u <= r[x].length && (e - P > t.css.fontSize.toPx() || e < P); ) {
                        if (P < e) b = r[x].substr(g, ++u); else {
                            if (b.length <= 1) break;
                            b = r[x].substr(g, --u);
                        }
                        P = this.ctx.measureText(b).width;
                    }
                    if (g += b.length, n === h - 1 && (x < r.length - 1 || g < r[x].length)) {
                        for (;this.ctx.measureText(b + "...").width > e && !(b.length <= 1); ) b = b.substring(0, b.length - 1);
                        b += "...", P = this.ctx.measureText(b).width;
                    }
                    this.ctx.setTextAlign(t.css.textAlign || "left");
                    var v = void 0;
                    switch (t.css.textAlign) {
                      case "center":
                        v = 0;
                        break;

                      case "right":
                        v = e / 2;
                        break;

                      default:
                        v = -e / 2;
                    }
                    var p = -i / 2 + (0 === n ? t.css.fontSize.toPx() : t.css.fontSize.toPx() + n * a);
                    n++, "stroke" === t.css.textStyle ? this.ctx.strokeText(b, v, p, P) : this.ctx.fillText(b, v, p, P);
                    var w = t.css.fontSize.toPx();
                    t.css.textDecoration && (this.ctx.beginPath(), /\bunderline\b/.test(t.css.textDecoration) && (this.ctx.moveTo(v, p), 
                    this.ctx.lineTo(v + P, p)), /\boverline\b/.test(t.css.textDecoration) && (this.ctx.moveTo(v, p - w), 
                    this.ctx.lineTo(v + P, p - w)), /\bline-through\b/.test(t.css.textDecoration) && (this.ctx.moveTo(v, p - w / 3), 
                    this.ctx.lineTo(v + P, p - w / 3)), this.ctx.closePath(), this.ctx.strokeStyle = t.css.color, 
                    this.ctx.stroke());
                }
                this.ctx.restore(), this._doBorder(t, e, i);
            }
        }
    }, {
        key: "_drawAbsRect",
        value: function(t) {
            this.ctx.save();
            var s = this._preProcess(t), e = s.width, i = s.height;
            GD.api.isGradient(t.css.color) ? GD.api.doGradient(t.css.color, e, i, this.ctx) : this.ctx.fillStyle = t.css.color;
            s = t.css.borderRadius, s = s ? Math.min(s.toPx(), e / 2, i / 2) : 0;
            this.ctx.beginPath(), this.ctx.arc(-e / 2 + s, -i / 2 + s, s, +Math.PI, 1.5 * Math.PI), 
            this.ctx.lineTo(e / 2 - s, -i / 2), this.ctx.arc(e / 2 - s, -i / 2 + s, s, 1.5 * Math.PI, 2 * Math.PI), 
            this.ctx.lineTo(e / 2, i / 2 - s), this.ctx.arc(e / 2 - s, i / 2 - s, s, 0, .5 * Math.PI), 
            this.ctx.lineTo(-e / 2 + s, i / 2), this.ctx.arc(-e / 2 + s, i / 2 - s, s, .5 * Math.PI, +Math.PI), 
            this.ctx.closePath(), this.ctx.fill(), this.ctx.restore(), this._doBorder(t, e, i);
        }
    }, {
        key: "_doShadow",
        value: function(t) {
            t.css && t.css.shadow && (4 < (t = t.css.shadow.replace(/,\s+/g, ",").split(" ")).length ? console.error("shadow don't spread option") : (this.ctx.shadowOffsetX = parseInt(t[0], 10), 
            this.ctx.shadowOffsetY = parseInt(t[1], 10), this.ctx.shadowBlur = parseInt(t[2], 10), 
            this.ctx.shadowColor = t[3]));
        }
    }, {
        key: "_getAngle",
        value: function(t) {
            return Number(t) * Math.PI / 180;
        }
    } ]), e;
}();

exports.default = Painter;